﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "../node/Sprite.h"
#include "CheckBox.h"
#include "../render/Camera.h"
#include "Text.h"
#include "Scale9Image.h"
#include "Geometry.h"
#include "../base/EventMouse.h"


namespace SkyEngine2d
{
	CheckBox::CheckBox(Widget* parent)
		:AbstractButton(parent)
		, m_checkState(CheckState::Unchecked)
	{
		this->setFocusPolicy(Widget::FocusPolicy::NoFocus);
	}
	
	CheckBox* CheckBox::create(Widget* parent /*= nullptr*/)
	{
		auto p = makeWidgetPtr(parent);
		if (p->init())
		{
			return p;
		}
	
		return nullptr;
	}
	
	void CheckBox::setTextRect(const Rect& rect)
	{
		if ( m_textRect == rect )
		{
			return;
		}
	
		m_textRect = rect;
	
		m_textRenderRect.origin = getAbsPos() + rect.origin;
		m_textRenderRect.size = rect.size;
	}
	
	void CheckBox::setCheckedFillImage(std::unique_ptr<Scale9Image> image, const Rect& rect)
	{
		m_fillImage = std::move(image);
		this->setCheckedFillImageRect(rect);
	}
	
	void CheckBox::setCheckedFillImageRect(const Rect& rect)
	{
		if (m_fillRect == rect)
		{
			return;
		}
	
		m_fillRect = rect;
		m_fillRenderRect.origin = this->getAbsPos() + rect.origin;
		m_fillRenderRect.size = rect.size;
	}
	
	void CheckBox::setChangeStateListener(const std::function<void(CheckState curr_state)>& listener)
	{
		m_checkStateListener = listener;
	}
	
	void CheckBox::setCheckState(CheckState state)
	{
		if (state == m_checkState)
		{
			return;
		}
	
		m_checkState = state;
	
		if (m_checkStateListener)
		{
			m_checkStateListener(m_checkState);
		}
	}
	
	CheckBox::CheckState CheckBox::getCheckState() const
	{
		return m_checkState;
	}
	
	void CheckBox::draw(IRender* render, const Matrix4X4& transform)
	{
		if (m_currentImage)
		{
			DirectX::XMMATRIX mvp = DirectX::XMMatrixMultiply(transform, getCamera()->getViewProjectMat());
			m_currentImage->draw(render,mvp);
		}
	
		if (m_textRender)
		{
			m_textRender->setDrawRect(m_textRenderRect);
			m_textRender->draw(render, Matrix4X4::IdentityMat);
		}
	
		if (m_checkState == CheckState::Checked)
		{
			if (m_fillImage)
			{
				m_fillImage->draw(render, m_fillRenderRect, this->getCamera());
			}
		}
	}
	
	
	bool CheckBox::init()
	{
		if (!AbstractButton::init())
		{
			return false;
		}
		return true;
	}
	
	void CheckBox::onMouseReleaseEvent(EventMouse* event)
	{
		AbstractButton::onMouseReleaseEvent(event);
	
		if (event->getButton() == EventMouse::ButtonType::Left)
		{
			if (m_checkState == CheckState::Checked)
			{
				this->setCheckState(CheckState::Unchecked);
			}
			else
			{
				this->setCheckState(CheckState::Checked);
			}
		}
	}
	
	void CheckBox::onMoveEvent(EventWidgetMove* e)
	{
		AbstractButton::onMoveEvent(e);
		m_textRenderRect.origin = getAbsPos() + m_textRect.origin;
		m_fillRenderRect.origin = getAbsPos() + m_fillRect.origin;
	}
	
	void CheckBox::onResizeEvent(EventResize* e)
	{
		AbstractButton::onResizeEvent(e);
	}
	
	int CheckBox::getDefultWidth() const
	{
		return 100;
	}
	
	int CheckBox::getDefultHeight() const
	{
		return 40;
	}
	
}
